#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "searchdialog.h"

#include <QAction>
#include <QDialog>
#include <QTableWidget>
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //setup UI
    ui->setupUi(this);
    QWidget::setWindowTitle ("Student management");


    ui->studentList->setColumnCount(6);
    ui->studentList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->studentList->setHorizontalHeaderItem(0, new QTableWidgetItem("ID"));
    ui->studentList->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
    ui->studentList->setHorizontalHeaderItem(2, new QTableWidgetItem("Age"));
    ui->studentList->setHorizontalHeaderItem(3, new QTableWidgetItem("Gender"));
    ui->studentList->setHorizontalHeaderItem(4, new QTableWidgetItem("Phone Number"));
    ui->studentList->setHorizontalHeaderItem(5, new QTableWidgetItem("Email"));

    applyFilter = new QPushButton("Apply filter",this);
    clearFilter = new QPushButton("Clear filter",this);
    filter = new QLineEdit(this);
    filterAs = new QComboBox(this);
    filterAs->addItem("ID");
    filterAs->addItem("Name");
    filterAs->addItem("Age");
    filterAs->addItem("Gender");
    filterAs->addItem("Phone Number");
    filterAs->addItem("Email");

    ui->statusBar->addPermanentWidget(filter);
    ui->statusBar->addPermanentWidget(filterAs);
    ui->statusBar->addPermanentWidget(applyFilter);
    ui->statusBar->addPermanentWidget(clearFilter);

    //connect actions
    connect(ui->actionAbout_Qt,SIGNAL(triggered()),this,SLOT(aboutQtDialog()));
    connect(ui->actionDelete,SIGNAL(triggered()),this,SLOT(deleteOne()));
    connect(ui->actionAdd,SIGNAL(triggered()),this,SLOT(add()));
    connect(ui->actionConnect_Database,SIGNAL(triggered()),this,SLOT(connectToFile()));
    connect(ui->actionDisconnect_Database,SIGNAL(triggered()),this,SLOT(disconnectFromFile()));
    connect(ui->actionDelete_All,SIGNAL(triggered()),this,SLOT(deleteAll()));
    connect(ui->actionSearch,SIGNAL(triggered()),this,SLOT(search()));
    connect(this->applyFilter,SIGNAL(clicked()),this,SLOT(filtering()));
    connect(this->clearFilter,SIGNAL(clicked()),this,SLOT(refresh()));
    connect(this,SIGNAL(connected()),this,SLOT(available()));
    connect(this,SIGNAL(disconnected()),this,SLOT(notAvailable()));

    //update database when an item changed
    connect(ui->studentList,SIGNAL(cellChanged(int,int)),this,SLOT(updateInfo(int,int)));

    //sort by column
    connect(ui->studentList->horizontalHeader(),SIGNAL(sectionClicked(int)),this,SLOT(sortBy(int)));
    connect(ui->studentList,SIGNAL(cellClicked(int,int)),ui->studentList,SLOT(selectRow(int)));
    emit disconnected();
    //connectToFile();
}

MainWindow::~MainWindow()
{
    this->disconnectFromFile();
    delete ui;
}

void MainWindow::deleteOne()
{    
    ui->studentList->removeRow (ui->studentList->currentRow());
    this->saveToFile();
}

void MainWindow::deleteAll()
{
    if(QMessageBox::Yes == QMessageBox::question(this,tr("Delete all student"),
                                                      tr("This will delete all students in the database. Are you sure?")))
    {
        ui->studentList->setRowCount(0);
        this->saveToFile();
    }
}

void inline MainWindow::add()
{
    ui->studentList->insertRow(ui->studentList->rowCount());
}


void MainWindow::connectToFile()
{
    fileName = QFileDialog::getOpenFileName(this,
        tr("Open Database"), "/", tr("Data files (*.txt)"));
    if (fileName != "")
    {
        ui->studentList->setRowCount(0);
    this->refresh();
    emit connected();
    } else emit disconnected();
}

void MainWindow::aboutQtDialog()
{
    QMessageBox::aboutQt(this,tr("About Qt"));
}

void MainWindow::refresh()
{
    disconnect(ui->studentList,SIGNAL(cellChanged(int,int)),this,SLOT(updateInfo(int,int)));
    ui->studentList->setRowCount(0);
    QFile data(fileName);
    if (data.open(QFile::ReadOnly))
    {
        QTextStream input(&data);
        QStringList lineAll = input.readAll().split("Â¶");
        this->add();
        ui->studentList->setRowCount(lineAll.size()/6 + 1);
        for (int i = 0; i<lineAll.size();++i)
        {
            static QTableWidgetItem *tempwid;
            tempwid = new QTableWidgetItem();
            tempwid->setText(lineAll.at(i));
            ui->studentList->setItem(static_cast<int>(i/6),static_cast<int>(i%6),tempwid);
        }
        data.close();
    }
    connect(ui->studentList,SIGNAL(cellChanged(int,int)),this,SLOT(updateInfo(int,int)));
}

void MainWindow::search()
{
    static SearchDialog *searchBox = new SearchDialog(this);
    if(searchBox->exec() != QDialog::Accepted)
        return;

    for(int i = 0; i < ui->studentList->rowCount(); ++i)
    {

        if(ui->studentList->item(i, 0) != NULL)
            if(!QString::compare(ui->studentList->item(i, 0)->text().trimmed(), searchBox->searchString().trimmed(), Qt::CaseInsensitive))
            {
                ui->studentList->selectRow(i);
                return;
            }
    }

    QMessageBox::information(this,tr("Not found!"),tr("Student ID not found!"));

}

void MainWindow::disconnectFromFile()
{
    file.close();
    ui->studentList->setRowCount(0);
    emit disconnected();
}

bool MainWindow::isIdValid(QString beingCheck) const
{
    if (beingCheck != "Invalid!")
    {
        if(beingCheck == "") return false;
        int cks = 0;
        for(int i = 0; i < ui->studentList->rowCount(); ++i)
        {
            if(ui->studentList->item(i, 0) != NULL)
                if(!QString::compare(ui->studentList->item(i, 0)->text().trimmed(), beingCheck.trimmed(), Qt::CaseInsensitive))
                    ++cks;
        }
        if (cks!=1) return false;
    }
    return true;
}

void MainWindow::updateInfo(int row, int column)
{
    QTableWidgetItem *currentChanged = ui->studentList->item(row,column);

    //check ID is valid
    if(0 == column)
    {
        if (!this->isIdValid(currentChanged->text()))
        {
            currentChanged->setBackgroundColor(Qt::red);
            //currentChanged->setText("");
            return;
        }
        currentChanged->setBackgroundColor(Qt::white);

    } else
    {
        this->saveToFile();
    }


}

void MainWindow::filtering()
{
    disconnect(ui->studentList,SIGNAL(cellChanged(int,int)),this,SLOT(updateInfo(int,int)));

    int filterRole = this->filterAs->currentIndex();
    for(int i = ui->studentList->rowCount()-1; i >-1 ; --i)
    {
        if(ui->studentList->item(i,filterRole) == NULL)
            continue;

        if(!ui->studentList->item(i,filterRole)->text().contains(this->filter->text(),Qt::CaseInsensitive))
            ui->studentList->removeRow(i);
    }
    connect(ui->studentList,SIGNAL(cellChanged(int,int)),this,SLOT(updateInfo(int,int)));
}

void MainWindow::available()
{
    ui->actionAdd->setEnabled(true);
    ui->actionDelete->setEnabled(true);
    ui->actionDelete_All->setEnabled(true);
    ui->actionDisconnect_Database->setEnabled(true);
    ui->actionConnect_Database->setDisabled(true);

    ui->statusBar->showMessage("Database connected!");
}

void MainWindow::notAvailable()
{
    ui->actionConnect_Database->setEnabled(true);
    ui->actionAdd->setDisabled(true);
    ui->actionDelete->setDisabled(true);
    ui->actionDelete_All->setDisabled(true);
    ui->actionDisconnect_Database->setDisabled(true);

    ui->statusBar->showMessage("Database not available!");
}

void MainWindow::saveToFile()
{
    QFile data(fileName);
    if (data.open(QFile::WriteOnly | QFile::Truncate ))
    {
        QTextStream out(&data);
        for(int i = 0; i < ui->studentList->rowCount();++i)
        {
            for (int j = 0; j< ui->studentList->columnCount();++j)
            {
                if(ui->studentList->item(i,j) == NULL)
                    out<<" ¶";
                else
                    out<<ui->studentList->item(i,j)->text()<<" ¶";
             }
        }

    }

    data.close();

}

void MainWindow::sortBy(int column)
{
    ui->studentList->sortByColumn(column);
    this->saveToFile();
}
